<?php

class Empeval_Methods_Request_SetBonusGoalsFrom2Status {
	
	private static $EMPLOYEE_TRANSITIONS = array(
			EmpevalBonusGoalsForms::STATUS_NEW 												=> array(EmpevalBonusGoalsForms::STATUS_IN_EDITION_1, EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1),
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_1 							=> array(EmpevalBonusGoalsForms::STATUS_NEW, EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1),
			EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1 			=> array(EmpevalBonusGoalsForms::STATUS_NEW, EmpevalBonusGoalsForms::STATUS_ACCEPTED_1),
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1				=> array(),
			EmpevalBonusGoalsForms::STATUS_ACCEPTED_1									=> array(EmpevalBonusGoalsForms::STATUS_IN_EDITION_2),
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_2								=> array(EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT, EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2),
			EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT => array(EmpevalBonusGoalsForms::STATUS_IN_EDITION_2, EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2),
			EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2						=> array(EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT, EmpevalBonusGoalsForms::STATUS_TO_CALCULATE),
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2				=> array(),
			EmpevalBonusGoalsForms::STATUS_TO_CALCULATE								=> array(),
			EmpevalBonusGoalsForms::STATUS_CALCULATING								=> array(),
			EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3						=> array(EmpevalBonusGoalsForms::STATUS_REJECTED, EmpevalBonusGoalsForms::STATUS_CLOSED),
			EmpevalBonusGoalsForms::STATUS_REJECTED										=> array(),
			EmpevalBonusGoalsForms::STATUS_CLOSED											=> array()
	);
	
	private static $SUPERIOR_TRANSITIONS = array(
			EmpevalBonusGoalsForms::STATUS_NEW 												=> array(EmpevalBonusGoalsForms::STATUS_IN_EDITION_1, EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1),
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_1 							=> array(EmpevalBonusGoalsForms::STATUS_NEW, EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1),
			EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1 			=> array(),
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1 			=> array(EmpevalBonusGoalsForms::STATUS_NEW, EmpevalBonusGoalsForms::STATUS_ACCEPTED_1),
			EmpevalBonusGoalsForms::STATUS_ACCEPTED_1 								=> array(EmpevalBonusGoalsForms::STATUS_IN_EDITION_2, EmpevalBonusGoalsForms::STATUS_CALCULATING),
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_2 							=> array(EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT, EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2),
			EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT => array(EmpevalBonusGoalsForms::STATUS_IN_EDITION_2, EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2),
			EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2						=> array(),
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2				=> array(EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT, EmpevalBonusGoalsForms::STATUS_TO_CALCULATE),
			EmpevalBonusGoalsForms::STATUS_TO_CALCULATE								=> array(EmpevalBonusGoalsForms::STATUS_CALCULATING, EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3),
			EmpevalBonusGoalsForms::STATUS_CALCULATING								=> array(EmpevalBonusGoalsForms::STATUS_TO_CALCULATE, EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3),
			EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3						=> array(),
			EmpevalBonusGoalsForms::STATUS_REJECTED										=> array(),
			EmpevalBonusGoalsForms::STATUS_CLOSED											=> array()
	);
	
	private static $SET_EDITOR = array(
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_1,
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_2,
			EmpevalBonusGoalsForms::STATUS_CALCULATING
	);
	
	private static $ADD_EMPLOYEE_ACCEPTANCE = array(
			EmpevalBonusGoalsForms::STATUS_NEW => EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1,
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_1 => EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1,
			EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1 => EmpevalBonusGoalsForms::STATUS_ACCEPTED_1,
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_2 => EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2,
			EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2 => EmpevalBonusGoalsForms::STATUS_TO_CALCULATE,
			EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT => EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2,
	);
	
	private static $ADD_SUPERIOR_ACCEPTANCE = array(
			EmpevalBonusGoalsForms::STATUS_NEW => EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1,
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_1 => EmpevalBonusGoalsForms::STATUS_TO_EMPLOYEE_ACCEPT_1,
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1 => EmpevalBonusGoalsForms::STATUS_ACCEPTED_1,
			EmpevalBonusGoalsForms::STATUS_IN_EDITION_2 => EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2,
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2 => EmpevalBonusGoalsForms::STATUS_TO_CALCULATE,
			EmpevalBonusGoalsForms::STATUS_WAITING_FOR_SEND_TO_ACCEPT => EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_2,
			EmpevalBonusGoalsForms::STATUS_TO_CALCULATE => EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3,
			EmpevalBonusGoalsForms::STATUS_CALCULATING => EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3,
	);
	
	private static $TO_SUPERIOR_ACCEPT_STATUSES = array(
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_1,
			EmpevalBonusGoalsForms::STATUS_TO_SUPERIOR_ACCEPT_2,
			EmpevalBonusGoalsForms::STATUS_TO_CALCULATE
	);
	
	/**
	 *
	 * @var App_Methods_Data_App
	 */
	public $app;
	public $bonusGoalsFormId;
	public $status;
	
	public function __construct($params) {
		$this->app = new App_Methods_Data_App($params->app);
		$this->bonusGoalsFormId = $params->bonusGoalsFormId;
		$this->status = $params->status;
	}
	
	public function process() {
		$formWithSuperiorUserPosition = EmpevalViewBgfWithSuperiorPositionIdQuery::create()
		->filterById($this->bonusGoalsFormId)
		->leftJoinUserPositionsRelatedBySuperiorUserPositionId('SuperiorUserPositions')
		->joinUserPositionsRelatedByUserPositionId()
		->with('SuperiorUserPositions')
		->with('UserPositionsRelatedByUserPositionId')
		->findOne();
		
		if (!($formWithSuperiorUserPosition instanceof EmpevalViewBgfWithSuperiorPositionId))
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
		
		if ($formWithSuperiorUserPosition->isEmployee(Empeval_Auth::getInstance()->getUser())) {
			$transitions = self::$EMPLOYEE_TRANSITIONS;
			if ($formWithSuperiorUserPosition->getSuperiorUserPositionId() == null && in_array($this->status, self::$TO_SUPERIOR_ACCEPT_STATUSES))
				throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_CHANGE_STATUS_WHEN_SUPERIOR_NOT_EXIST);
		}
		else if ($formWithSuperiorUserPosition->isSuperior(Empeval_Auth::getInstance()->getUser())) {
			$transitions = self::$SUPERIOR_TRANSITIONS;
		}
		else if (Empeval_Auth::getInstance()->getUser()->isHr()) {
			return $this->hrMode();
		}
		else {
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
		}
		
		$bonusGoalsForm = EmpevalBonusGoalsFormsQuery::create()
		->filterById($this->bonusGoalsFormId)
		->joinUserPositions()
		->with('UserPositions')
		->findOne();
	
		if (!($bonusGoalsForm instanceof EmpevalBonusGoalsForms))
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
		
		if (!in_array($this->status, $transitions[$bonusGoalsForm->getStatus()]))
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
	
		if (in_array($bonusGoalsForm->getStatus(), self::$SET_EDITOR) && $bonusGoalsForm->getEditorId() != Empeval_Auth::getInstance()->getUser()->getId())
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
	
		if (in_array($this->status, self::$SET_EDITOR))
			$bonusGoalsForm->setEditorId(Empeval_Auth::getInstance()->getUser()->getId());
		else
			$bonusGoalsForm->setEditorId(null);
	
		if (array_key_exists($bonusGoalsForm->getStatus(), self::$ADD_EMPLOYEE_ACCEPTANCE) && self::$ADD_EMPLOYEE_ACCEPTANCE[$bonusGoalsForm->getStatus()] == $this->status) {
			$acceptance = new EmpevalAcceptance();
			$acceptance->setUsers(Empeval_Auth::getInstance()->getUser());
			$acceptance->setType(EmpevalAcceptance::TYPE_EMPLOYEE);
			$acceptance->setStatusFrom($bonusGoalsForm->getStatus());
			$acceptance->setStatusTo($this->status);
			$bonusGoalsForm->addAcceptance($acceptance);
		}
		else if (array_key_exists($bonusGoalsForm->getStatus(), self::$ADD_SUPERIOR_ACCEPTANCE) && self::$ADD_SUPERIOR_ACCEPTANCE[$bonusGoalsForm->getStatus()] == $this->status) {
			$acceptance = new EmpevalAcceptance();
			$acceptance->setUsers(Empeval_Auth::getInstance()->getUser());
			$acceptance->setType(EmpevalAcceptance::TYPE_SUPERIOR);
			$acceptance->setStatusFrom($bonusGoalsForm->getStatus());
			$acceptance->setStatusTo($this->status);
			$bonusGoalsForm->addAcceptance($acceptance);
		}
	
		$bonusGoalsForm->setStatus($this->status);
		$bonusGoalsForm->save();
		
		if ($this->status == EmpevalBonusGoalsForms::STATUS_TO_USER_ACCEPT_3) {
			$notification = new Empeval_Notifications_Calculated();
			$notification->addNotifications($bonusGoalsForm->getUserPositions()->getUserId(), $bonusGoalsForm->getId());
		}
	
		return new Empeval_Methods_Response_SetBonusGoalsFromStatus(true, $this->status);
	}
	
	public function hrMode() {
		$bonusGoalsForm = EmpevalBonusGoalsFormsQuery::create()
		->filterById($this->bonusGoalsFormId)
		->findOne();
	
		if (!($bonusGoalsForm instanceof EmpevalBonusGoalsForms))
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
	
		if ($this->status == 1) {
			$bonusGoalsForm->setTmpStatus($bonusGoalsForm->getStatus());
			$bonusGoalsForm->setStatus(EmpevalBonusGoalsForms::STATUS_HR_EDIT);
			$bonusGoalsForm->setEditorId(Empeval_Auth::getInstance()->getUser()->getId());
			$bonusGoalsForm->save();
		}
		else if ($this->status == 0) {
			$bonusGoalsForm->setStatus($bonusGoalsForm->getTmpStatus());
			$bonusGoalsForm->setTmpStatus(null);
			$bonusGoalsForm->setEditorId(null);
			$bonusGoalsForm->save();
		} else {
			throw new Empeval_Exception_App(Empeval_Exception_Codes::INFO_ACCESS_DENIED);
		}
	
		return new Empeval_Methods_Response_SetBonusGoalsFromStatus(true, $bonusGoalsForm->getStatus());
	}
	
}